#pragma once
union Vector2;
union Vector3;
union Vector4;
union Matrix;
union Quaternion;

namespace VectorHelper
{
	namespace Matricies
	{
		// translate by the given ammount
		Matrix CreateTranslation(const Vector3& v);

		// rotate around the 'x' axis
		Matrix CreateRotationX(float radians);
		// rotate around the 'y' axis
		Matrix CreateRotationY(float radians);
		// rotate around the 'z' axis
		Matrix CreateRotationZ(float radians);

		// create a scale matrix with the provided scale
		Matrix CreateScale(float scale);
		Matrix CreateScale(float scale_x, float scale_y, float scale_z);

		// create a camera look at matrix
		Matrix CreateLookAt(Vector3& cameraPosition, Vector3& cameraLookAt, Vector3& cameraUp);

		// create a perspective matrix with field of view
		Matrix CreatePerspectiveFieldOfView(float fov, float aspectRatio, float nearPlaneDistance, float farPlaneDistance);

		// create an axis rotation from an arbitrary axis angle
		Matrix CreateFromAxisAngle(Vector3& axis, float angle);

		// create an orthographic persepctive matrix
		Matrix CreateOrthographicOffCenter(float left, float right, float bottom, float top, float zNear, float zFar);

		// invert a matrix
		Matrix Invert(Matrix& matrix);

		// computes the determinate for a matrix
		float Determinant(Matrix& matrix);

		// computes the transpose of the matrix
		Matrix Transpose(Matrix& matrix);

		// The identity matrix
		extern Matrix Identity;
	}

	namespace vector_3
	{
		// a vector in the direction { 0, 1, 0 }
		extern Vector3 up;
		// a vector in the direction { 0, -1, 0 }
		extern Vector3 down;
		// a vector in the direction { -1, 0, 0 }
		extern Vector3 left;
		// a vector in the direction { 1, 0, 0 }
		extern Vector3 right;
		// a vector in the direction { 0, 0, 1 }
		extern Vector3 forward;
		// a vector in the direction { 0, 0, -1 }
		extern Vector3 backward;

		// interpolate between two 3-dimentional vectors
		Vector3 Lerp(Vector3& a, Vector3& b, float ammount);
		
		// a zero 3-component vector
		extern Vector3 Zero;
	}

	namespace vector_2
	{
		// a zero, 2-component vector
		extern Vector2 Zero;

		// interpolate between two 2-dimentional vectors
		Vector2 Lerp(Vector2& a, Vector2& b, float ammount);
	}

	namespace vector_4
	{
		extern Vector4 Zero;

		extern Vector4 red;
		extern Vector4 green;
		extern Vector4 blue;
		extern Vector4 yellow;
		extern Vector4 fuckUgly_magenta;
		extern Vector4 black;
		extern Vector4 white;
		extern Vector4 transparent;
		extern Vector4 brown;
		extern Vector4 gray;
		
		// interpolate between two 4-dimentional vectors
		Vector4 Lerp(Vector4& a, Vector4& b, float ammount);
	}

	namespace Quaternoins
	{
		Quaternion CreateFromAxisAngle(Vector3& axis, float angle);
		Quaternion CreateFromYawPitchRoll(float yaw, float pitch, float roll);
		Quaternion CreateFromRotationMatrix(Matrix&);
	}

	float distance(Vector2&, Vector2&);
	float distance(Vector3&, Vector3&);
	float distance(Vector4&, Vector4&);
}